package top.easyblog.core.support.filter;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import top.easyblog.common.constant.TransformStatus;
import top.easyblog.core.service.MappingVisitRecordService;

import javax.servlet.http.HttpServletResponse;
import java.net.URI;

import static org.springframework.web.cors.CorsConfiguration.ALL;

/**
 * 重定向转换过滤器
 */
@Slf4j
@Component
@RequiredArgsConstructor
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class RedirectionTransformFilter implements TransformFilter {

    private final MappingVisitRecordService mappingVisitRecordService;

    @Override
    public void init(TransformContext context) {

    }

    @Override
    public void doFilter(TransformFilterChain chain, TransformContext context) {
        if (TransformStatus.TRANSFORM_SUCCESS == context.getTransformStatus()) {
            String longUrlString = context.getParam(TransformContext.PARAM_LONG_URL_KEY);
            try {
                if (StringUtils.isNotBlank(longUrlString)) {
                    Runnable redirectAction = redirectAction(
                            context.getParam(TransformContext.PARAM_HTTP_SERVLET_RESPONSE),
                            longUrlString
                    );

                    context.setRedirectAction(redirectAction);
                    context.setParam(TransformContext.PARAM_TARGET_LONG_URL_KEY, longUrlString);
                    context.setTransformStatus(TransformStatus.REDIRECTION_SUCCESS);
                } else {
                    context.setTransformStatus(TransformStatus.REDIRECTION_FAIL);
                    log.warn("重定向到长链接失败,长链值为空,压缩码:{}", context.getCompressionCode());
                }
            } catch (Exception e) {
                log.error("重定向到长链接[{}]失败,压缩码:{}", longUrlString, context.getCompressionCode(), e);
                context.setTransformStatus(TransformStatus.REDIRECTION_FAIL);
            } finally {
                mappingVisitRecordService.sendMappingVisitMessage(context);
            }
        }
        chain.doFilter(context);
    }

    private Runnable redirectAction(HttpServletResponse response, String url) {
        return () -> {
            response.setStatus(HttpStatus.FOUND.value());
            response.setHeader(HttpHeaders.LOCATION, URI.create(url).toString());
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, ALL);
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, ALL);
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.TRUE.toString());
        };
    }

    @Override
    public int order() {
        return Integer.MAX_VALUE;
    }

}
